/*-------------------------------------------------------------------------

***************** Modification History ***********************************
   @doc
   @module SDT.c - Shift Definition Table global variable |
   @end
   
$Log: /SoftPay/SPK2SIM/Source/Shift/sdt.c $ 
**************************************************************************

   Copyright (C) 1999 by VeriFone, Inc.

   All rights reserved.  No part of this software may be reproduced,
   transmitted, transcribed, stored in a retrieval system, or translated
   into any language or computer language, in any form or by any means,
   electronic, mechanical, magnetic, optical, chemical, manual or otherwise,
   without the prior written permission of VeriFone, Inc.

---------------------------------------------------------------------------*/
#include <project.h>

#ifdef SHIFT_DEFINED

#ifndef SDT_C
#define SDT_C

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <aclstr.h>
#include <ascii.h>
#include <dbmgr.h>

#ifdef DEBUG_VSTCT
#define DEBUG_95
#endif

#include <define.h>
#include <transact.h>
#include <sdt.h>
#include <gds.h>
#include <cdt.h>
#include <hdt.h>
#include <mit.h>
#include <tct.h>
#include <confio.h>
#include <msg.h>
#include <msgfuncs.h>
#include <msgshf.h>
#include <fields.h>
#include <tran.h>
#include <oper.h>    /* pj1 */
#include <funcids.h>
#include <entry.h>
#include <ui.h>
#include <spdebug.h>
#include <util.h>
#include <file.h>
#include <spdebug.h>
#include <sizes.h>

/* Local variable storing the current SDT entry */

SDT_REC srSDTRec;


/********************************************************************************************* 
* @func int | vdGetSTTFileName |
*       
*returns the corresponding STT file name based on the host
*                   Eg.         Host number  3, offline - VSUTT03
*                               Host number 24, online  - VSUTT24(
*
*
* @rdesc return values.
* @flag int    |  no return value
* @end
**********************************************************************************************/

void vdGetSTTFileName(char* pchSTTFileName) {
    sprintf(pchSTTFileName, "SST%02d%02d", inGetBatchIndex(), inGetMerchantNum());
}

/********************************************************************************************* 
* @func int | inOpenSTT |
*       
* Opens/Creates the desired STT file.
*
* @rdesc return values.
* @flag int    |  VS_ERR, VS_SUCCESS
* @end
**********************************************************************************************/

int inOpenSTT(DB_FILE* psrDBFPtr,char* pchFName) {
    int inRetVal;


    inRetVal = db_open(psrDBFPtr, pchFName, SIZE_STT_KEY, O_RDWR);

    if (inRetVal < 0) /* If file is non-existant, create it */
        inRetVal = db_open(psrDBFPtr, pchFName, SIZE_STT_KEY, (O_CREAT | O_RDWR));

    if (inRetVal < 0)
        return(VS_ERR);

    return(VS_SUCCESS);
}

/********************************************************************************************* 
* @func int | inCloseSTT |
*       
* Opens/Closes the STT file.
*
* @rdesc return values.
* @flag int    |  VS_ERR, VS_SUCCESS
* @end
**********************************************************************************************/

int inCloseSTT(DB_FILE* psrDBFPtr) {
    if (db_close(psrDBFPtr) > 0)
        return(VS_SUCCESS);

    return(VS_ERR);
}



/********************************************************************************************* 
* @func int | inSTTCompareFn |
*    This function will be called by the following function, as
*     one of the parameters of the db_get_key() function.
*   
* 
* @rdesc return values.
* @flag int    |  VS_ERR, VS_SUCCESS
* @end
**********************************************************************************************/

int inSTTCompareFn(STT_KEY* psrKey,STT_SKEY* MatchKey) {
    int inRetVal;

    inRetVal = VS_SUCCESS;

    /* pdebug(("--inSTTCompareFn--"));  */

    /* Search on Shift Id */
    if (MatchKey->sttKey.chShift != psrKey->chShift)
        inRetVal = VS_ERR;

    /* pdebug(("inRetVal = %d",inRetVal));  */
    return(inRetVal);
}

/********************************************************************************************* 
* @func int | inKeyReadSTT |
*       
* Reads the desired record from the STT
*
*  Before Calling this function ensure the following:
*                 1. Fill the srKey struct with relevant values
*                 2. Set the global 'inSearchIndex' variable to the search
*                    field index.  .
*
* @rdesc return values.
* @flag int    |  VS_ERR, VS_SUCCESS
* @end
**********************************************************************************************/

int inKeyReadSTT(DB_FILE* psrDBFPtr,STT_REC* psrRec,STT_KEY* psrKey,int inKeyIdx,long* plnRecNum) {
    long lnRetVal;
    long lnDBWhat = DB_FIRST;
    STT_SKEY srSTTSKey;

    /*
    *      Load Global Key Values used by inSTTCompFn
    */
    srSTTSKey.compare_func = inSTTCompareFn;
    memcpy(&srSTTSKey.sttKey, psrKey, SIZE_STT_KEY);
    lnRetVal = db_get_key(psrDBFPtr, psrKey, &srSTTSKey, lnDBWhat, (char *) psrRec, SIZE_STT_REC, plnRecNum);

    if (lnRetVal == 0L) {
        memset(psrRec, '\0', SIZE_STT_REC);
        return (VS_ERR);
    } else if (lnRetVal == -1L)
        return (VS_ESCAPE);
    return (VS_SUCCESS);
}


/********************************************************************************************* 
* @func int | inGetKeySTTRec |
*    
*     Find indexed STT record
*   
* 
* @rdesc return values.
* @flag int    |  VS_ESCAPE, VS_SUCCESS
* @end
**********************************************************************************************/

int inGetKeySTTRec(DB_FILE* psrDBFPtr,STT_REC* psrRec,STT_KEY* psrKey,int inKeyIdx,long lnDBWhat) {
    long lnRetVal,
    lnRecNum = 0L;
    STT_SKEY srSTTSKey;



    /*
     *      Load Global Key Values used by inSTTCompFn
     */
    srSTTSKey.compare_func = inSTTCompareFn;
    memcpy(&srSTTSKey.sttKey, psrKey, sizeof(STT_KEY));
    lnRetVal = db_get_key(psrDBFPtr, psrKey, &srSTTSKey, lnDBWhat, (char *) psrRec, SIZE_STT_REC, &lnRecNum);

    if (lnRetVal == 0L) {
        memset(psrRec, '\0', SIZE_STT_REC);
        return (VS_ERR);
    } else if (lnRetVal == -1L)
        return (VS_ESCAPE);
    return (VS_SUCCESS);
}

/********************************************************************************************* 
* @func int | inSetSTTAmount |
*    
*     Copy sale amounts from the transaction to a STT record
*   
* 
* @rdesc return values.
* @flag int    |  VS_ERR, VS_SUCCESS
* @end
**********************************************************************************************/


int inSetSTTAmount(TRANSACTION_OBJECT* pobTran) {
    int inCount;
    int inTranCode;
    char chShift;
    long lnBaseAmt,
    lnTipAmt,
    lnTaxAmt,
    lnCashBack,
    lnSurcharge,
    lnTipSale;
    long lnTotalOfTransAmount,
    lnTipAmount,
    lnOldTotalTransAmount,
    lnOldTipAmount;
    int inType;
    long lnTaxCBSurCharge;   /* Sum of Tax + CashBack + SurCharge */

    inCount = 0;
    lnBaseAmt = 0L;
    lnTaxAmt = 0L;
    lnTipAmt = 0L;
    lnCashBack = 0L;
    lnSurcharge = 0L;
    lnTipSale = 0L;

    lnOldTotalTransAmount = 0L;
    lnOldTipAmount = 0L;
    lnTotalOfTransAmount = 0L;
    lnTipAmount = 0L;

    inTranCode = inGGCode();

    lnOldTotalTransAmount = pobTran->srBRec.lnOldTotalTransactionAmount;
    lnTotalOfTransAmount = pobTran->srBKey.lnTotalOfTransactionAmount;
    lnTipAmount = pobTran->srBRec.lnTipAmount;
    lnOldTipAmount = pobTran->srBRec.lnOldTipAmount;
    lnTaxCBSurCharge = (pobTran->srBRec.lnTaxAmount + pobTran->srBRec.lnCashBackAmount + pobTran->srBRec.lnSChgAmount);

    chShift = pobTran->srBKey.chShift;

    inType = pobTran->srBRec.inType;
    if (inType == ADJUST_CREDIT_TRAN)
        inType = CREDIT_TRAN;
    if (inType == ADJUST_DEBIT_TRAN)
        inType = DEBIT_TRAN;

    if ((inType == DEBIT_TRAN) && !(pobTran->fAdjust || pobTran->fTipAdjust)) {
        inCount = 1;
        lnTaxAmt = pobTran->srBRec.lnTaxAmount;
        lnCashBack = pobTran->srBRec.lnCashBackAmount;
        lnSurcharge = pobTran->srBRec.lnSChgAmount;

        lnTipAmt = pobTran->srBRec.lnTipAmount;
        lnBaseAmt = (lnTotalOfTransAmount - lnTipAmt - lnTaxAmt - lnCashBack - lnSurcharge);

        if (pobTran->srBRec.lnTipAmount > 0)
            lnTipSale = lnBaseAmt;
        else
            lnTipSale = 0L;
    }

    if ((inType == CREDIT_TRAN) && !(pobTran->fAdjust || pobTran->fTipAdjust)) {
        inCount = 1;
        lnTaxAmt = -pobTran->srBRec.lnTaxAmount;
        lnCashBack = -pobTran->srBRec.lnCashBackAmount;
        lnSurcharge = -pobTran->srBRec.lnSChgAmount;

        lnTipAmt = -pobTran->srBRec.lnTipAmount;
        lnTotalOfTransAmount *= -1L;
        lnBaseAmt = (lnTotalOfTransAmount - lnTipAmt - lnTaxAmt - lnCashBack - lnSurcharge);

        if (pobTran->srBRec.lnTipAmount > 0)
            lnTipSale = lnBaseAmt;
        else
            lnTipSale = 0L;
    }

    if ((inType == DEBIT_TRAN) && (pobTran->fAdjust || pobTran->fTipAdjust)) {
        inCount = 0;
        lnTaxAmt = 0L;     /* can not adjust tax, cashback, surcharge */
        lnCashBack = 0L;
        lnSurcharge = 0L;

        if (pobTran->fTaxAdjust)
            lnTaxAmt = (pobTran->srBRec.lnTaxAmount - pobTran->lnOldTaxAmount);
        if (pobTran->fAdjust) {
            lnBaseAmt = (lnTotalOfTransAmount - pobTran->srBRec.lnTaxAmount) - (lnOldTotalTransAmount - pobTran->lnOldTaxAmount);

            if (pobTran->srBRec.lnTipAmount == pobTran->srBRec.lnOldTipAmount)
                lnTipAmt = 0L;
            else {
                lnTipAmt = (pobTran->srBRec.lnTipAmount - pobTran->srBRec.lnOldTipAmount);
                lnBaseAmt -= lnTipAmt;
            }

            if (lnTipAmount > 0)
                lnTipSale = lnBaseAmt;
            else
                lnTipSale = 0L;
        } else if (pobTran->fTipAdjust) {
            lnTipAmt = (lnTipAmount - lnOldTipAmount);
            lnBaseAmt = 0L;

            /* the case of both lnTipAmount and lnOldTipAmount > 0  */
            /*  or both = 0             has no effect on lnTipSale  */
            if (lnTipAmount == 0 && lnOldTipAmount > 0)
                lnTipSale = -(lnOldTotalTransAmount - lnOldTipAmount - lnTaxCBSurCharge);

            if (lnTipAmount > 0 && lnOldTipAmount == 0)
                lnTipSale = lnTotalOfTransAmount - lnTipAmount - lnTaxCBSurCharge;
        }
    }

    if ((inType == CREDIT_TRAN) && (pobTran->fAdjust || pobTran->fTipAdjust)) {
        inCount = 0;
        lnTaxAmt = 0L;     /* can not adjust tax, cashback, surcharge */
        lnCashBack = 0L;
        lnSurcharge = 0L;

        if (pobTran->fTaxAdjust)
            lnTaxAmt = -(pobTran->srBRec.lnTaxAmount - pobTran->lnOldTaxAmount);
        if (pobTran->fAdjust) {
            lnBaseAmt = -((lnTotalOfTransAmount - pobTran->srBRec.lnTaxAmount) - (lnOldTotalTransAmount - pobTran->lnOldTaxAmount));

            if (pobTran->srBRec.lnTipAmount == pobTran->srBRec.lnOldTipAmount)
                lnTipAmt = 0L;
            else {
                lnTipAmt = -(pobTran->srBRec.lnTipAmount - pobTran->srBRec.lnOldTipAmount);
                lnBaseAmt -= lnTipAmt;
            }

            if (lnTipAmount > 0)
                lnTipSale = lnBaseAmt;
            else
                lnTipSale = 0L;
        } else if (pobTran->fTipAdjust) {
            lnTipAmt = -(lnTipAmount - lnOldTipAmount);
            lnBaseAmt = 0L;

            /* the case of both lnTipAmount and lnOldTipAmount > 0  */
            /*  or both = 0             has no effect on lnTipSale  */
            if (lnTipAmount == 0 && lnOldTipAmount > 0)
                lnTipSale = (lnOldTotalTransAmount - lnOldTipAmount - lnTaxCBSurCharge);

            if (lnTipAmount > 0 && lnOldTipAmount == 0)
                lnTipSale = -(lnTotalOfTransAmount - lnTipAmount - lnTaxCBSurCharge);
        }
    }

    if (pobTran->srBKey.fVoided)
        return(inUpdateSTTRecord(pobTran, chShift, -1, (lnBaseAmt * -1L), (lnTaxAmt * -1L), (lnTipAmt * -1L), (lnCashBack * -1L), (lnSurcharge * -1L), (lnTipSale * -1L)));
    else
        return(inUpdateSTTRecord(pobTran, chShift, inCount, lnBaseAmt, lnTaxAmt, lnTipAmt, lnCashBack, lnSurcharge, lnTipSale));
}

/********************************************************************************************* 
* @func int | inUpdateSTTRecord |
*    
* Updates the specific SDT Record with given totals
*  Input Parameters :   inShift, inHost, inCnt, lnTot, lnTip, lnCsh
*                       lnRfnd, lnSurcharge, lnTipSale, lnTipRefund    
*   
* 
* @rdesc return values.
* @flag int    |  VS_ERR, VS_SUCCESS
* @end
**********************************************************************************************/


int inUpdateSTTRecord(TRANSACTION_OBJECT* pobTran,char chShift,int inCnt,long lnBase,long lnTax,long lnTip,long lnCsh,long lnSurcharge,long lnTipSale) {
    char szSTTFileName[FILENAME_SIZE + 1];
    DB_FILE srDBFPtr;
    STT_REC srSTTRec;
    STT_KEY srSTTKey;
    //   int inKeyIdx=0;
    long lnRecNum = 0L;
    int inRetVal;

    srSTTKey.chShift = chShift;

    vdGetSTTFileName(szSTTFileName);

    if (inOpenSTT(&srDBFPtr, szSTTFileName) != VS_SUCCESS) {
        vdSGErrorMessage(STT_ERR_MSG21);
        return(VS_ERR);
    }

    /* If record does not exist then append new record */

    inRetVal = inKeyReadSTT(&srDBFPtr, &srSTTRec, &srSTTKey, KEY_SHIFT, &lnRecNum);

    if (inRetVal == VS_ERR) {
        lnRecNum = DB_APPEND;
        srSTTKey.chShift = chShift;
    } else if (inRetVal == VS_ESCAPE) {
        inCloseSTT(&srDBFPtr);
        return (VS_ERR);
    }

    srSTTRec.inNetCount += inCnt;
    srSTTRec.lnNetTotAmt += lnBase + lnTax + lnTip + lnCsh + lnSurcharge;
    srSTTRec.lnNetBaseAmt += lnBase;
    srSTTRec.lnNetTaxAmt += lnTax;
    srSTTRec.lnNetTipAmt += lnTip ;
    srSTTRec.lnNetCashBack += lnCsh;
    srSTTRec.lnNetSurcharge += lnSurcharge;
    srSTTRec.lnTipSale += lnTipSale;

    /* Save the information */

    if (db_write(&srDBFPtr, &srSTTKey, (char *) &srSTTRec, SIZE_STT_REC, lnRecNum) < 0) {
        vdSGErrorMessage(STT_ERR_MSG21);
        inCloseSTT(&srDBFPtr);
        return(VS_ERR);
    }
    inRetVal = inCloseSTT(&srDBFPtr);

    return(VS_SUCCESS);
}

/********************************************************************************************* 
* @func int | inResetSTT |
*    
*   Clear out the active STT file
* 
* @rdesc return values.
* @flag int    |  VS_ERR, VS_SUCCESS
* @end
**********************************************************************************************/


int inResetSTT(TRANSACTION_OBJECT* pobtran) {
    int inRetval;
    char szFileName[FILENAME_SIZE + 1];
    DB_FILE srDBFPtr;

    vdGetSTTFileName(szFileName);
    if ((db_open(&srDBFPtr, szFileName, SIZE_STT_KEY, (O_TRUNC | O_CREAT | O_RDWR))) < 0)
        return(VS_ERR);
    inRetval = inCloseSTT(&srDBFPtr);

    return (inRetval);
}


#endif


#endif
